#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
if os.name == 'posix':
    from PenPresenter.xlibpainter import Painter
elif os.name == 'nt':
    #from directxpainter import Painter
    pass
from threading import Timer
from math import sqrt
import uno

MODO_COMANDO    = 0
MODO_MOVIMENTO  = 1
MODO_CANETA     = 2

TIMEOUT_COMANDO   = 0.5
TIMEOUT_MOVIMENTO = 0.25
TIMEOUT_CANETA    = 2.0

class OpenOffice:
    def __init__(self):
        self.modo = MODO_COMANDO
        self.pontos = []
        self.objeto_atual = None
        self.timer = None
        self.painter = Painter()
    def conectar(self, porta):
        try:
            local = uno.getComponentContext()
            resolver = local.ServiceManager.createInstanceWithContext (
              "com.sun.star.bridge.UnoUrlResolver", local)
            context = resolver.resolve(
              "uno:socket,host=localhost,port=%s;urp;StarOffice.ComponentContext" % porta)
            desktop = context.ServiceManager.createInstanceWithContext(
              "com.sun.star.frame.Desktop", context)
            self.doc = desktop.getCurrentComponent()
            self.presentation = self.doc.Presentation
            if self.presentation:
                return True
            else:
                return False
        except:
            return False
    #Interação com o cliente PenPresenter
    def laserRecebido(self, x, y):
        if self.modo == MODO_COMANDO:
            if self.timer:
                self.timer.cancel()
            self.timer = Timer(TIMEOUT_COMANDO, self.timeout)
            self.timer.start()
            self.pontos.append([x,y])
        elif self.modo == MODO_MOVIMENTO:
            pass
        elif self.modo == MODO_CANETA:
            self.painter.adicionarPonto(x,y)
            self.painter.desenharUltimos()
            if self.timer:
                self.timer.cancel()
            self.timer = Timer(TIMEOUT_CANETA, self.timeout)
            self.timer.start()
    def timeout(self):
        if self.modo == MODO_COMANDO:
            funcao = self.interpretarComando()
            if funcao:
                funcao()
        elif self.modo == MODO_CANETA:
            #self.painter.apagarAnotacoes()
            self.modo = MODO_COMANDO
    def interpretarComando(self):
        if not self.pontos:
            return None
        #Cálculo da média, máximo e mínimo
        media_x = float(0.0)
        media_y = float(0.0)
        for ponto in self.pontos:
            media_x += float(ponto[0])
            media_y += float(ponto[1])
        media_x /= len(self.pontos)
        media_y /= len(self.pontos)
        #Cálculo da variância
        desviopadrao_x = float(0.0)
        desviopadrao_y = float(0.0)
        for ponto in self.pontos:
            desviopadrao_x += (float(ponto[0]) - media_x)**2
            desviopadrao_y += (float(ponto[1]) - media_y)**2
        desviopadrao_x /= len(self.pontos)
        desviopadrao_y /= len(self.pontos)
        desviopadrao_x = sqrt(desviopadrao_x)
        desviopadrao_y = sqrt(desviopadrao_y)
        #Direção
        direcao_direita = self.pontos[0][0] < self.pontos[-1][0]
        direcao_baixo = self.pontos[0][1] < self.pontos[-1][1]
        print "Estatísticas (dvx,dvy): ", desviopadrao_x, desviopadrao_y
        #Limpando lista de pontos
        self.pontos = []
        #Interpretando linha horizontal
        try:
            relacaoxy = float(desviopadrao_x) / float(desviopadrao_y)
            print "Relação xy ", relacaoxy
        except ZeroDivisionError:
            relacaoxy = 6.0
        if relacaoxy > 2.5:
            if direcao_direita:
                print "PRÓXIMO SLIDE"
                return self.avancarSlide
            else:
                print "SLIDE ANTERIOR"
                return self.retrocederSlide
        #Interpretando linha vertical
        elif relacaoxy < 0.4:
            if direcao_baixo:
                self.modo = MODO_CANETA
                print "MODO CANETA"
                return None
            else:
                return None
        else:
            return None

    #Comandos OpenOffice
    def avancarSlide(self):
        controller = self.presentation.Controller
        if controller:
            controller.gotoNextSlide()
    def retrocederSlide(self):
        controller = self.presentation.Controller
        if controller:
            controller.gotoPreviousSlide()

#Padrão de projeto Singleton
single_oo = OpenOffice()
